x

Ad-hoc (перегрузка)

  • Вид полиморфизма, связываемый на этапе компиляции (статическое связывание), при котором в одном классе (или наследниках) существуют методы с одинаковым именем, но разными сигнатурами

Приоритет выбора компилятором

  1. Точное совпадение типов
  2. Расширение примитивов (int -> long -> float -> double)
  3. Автоупаковка/автораспаковка (int -> Integer)
  4. Переменное число аргументов (varargs)
    Два преобразования за раз компилятор сделать не может (например, сначала распаковать Integer в int, а затем привести к double) и будет ошибка компиляции

Приоритет с объектами

Приоритет отдается более специфичному типу

public static void print(Object o) {sout("Obj");}
public static void print(String s) {sout("String");}

print(null); // String

Если конфликт типов (на одном уровне иерархии), то ошибка компиляции

P.S

  • Можно перегружать с абсолютно разными модификаторами, типами исключений, статик и нон-статик и т.п.
  • Для модификаторов доступа - главное текущий scope. Компилятор сам определит какие методы сейчас можно вызвать в данной области видимости, затем, если надо преобразуя (по приоритетам, описанным ранее), вызовет метод
  • Самое главное - различие сигнатуры

Перегрука + Наследование

  • Выбор сигнатуры перегруженного метода происходит во время компиляции на основе типа ссылки, а не типа объекта в памяти
  • Если вызвать перегруженный метод через ссылку родительского типа (Parent p = new Child()), компилятор проигнорирует все методы, объявленные только в Child
  • В рантайме вызовется переопределенный метод (если он был переопределен), но строго с той сигнатурой, которую выбрал компилятор
Left-click: follow link, Right-click: select node, Scroll: zoom
x